<!--
*@Author: QWP
*@Description: 人员基本信息编辑
*@Date: 2024-07-08 17:04:38
-->
<template>
  <u-dialog v-bind="$attrs"
    :confirmLoading="formLoading"
    destroyOnClose
    :hideBtns="isCheck ? ['submit'] : []"
    :zIndex="800"
    @submit="submit"
    @close="dialogClose">
    <a-layout class="f-h-100 u-personal-manager-edit"
      id="u-personal-edit-box">
      <a-layout-sider width="180px"
        class="u-sider-box"
        v-if="(formInfo['base'] || {})['keyid']">
        <a-anchor v-if="refreshAnchor"
          :items="collapses.map(i => ({key: i.activeKey, href: `#${i.activeKey}`, title: i.label}))"
          :get-current-anchor="getCurrentAnchor"
          @click="handleClick"
        />
      </a-layout-sider>

      <a-layout-content id="baseContent" style="height: calc(100vh - 124px); overflow: hidden">
        <u-flow-tab activeKey="1"
          :show="isValue(formInfo['base']['status'])"
          :processId="current['processintsid']"
          :params="{ type: 'person_info', ...current }"
          :isAudit="formInfo['base']['status'] == 2"
          :isAuditPage="route.params.pType == '2'"
          v-bind="$attrs"
          class="u-person-flow-tab"
          ref="auditRef">
          <a-tab-pane key='1' tab="人事信息">
            <u-table-header v-if="!formInfo['base']['keyid']">
              <a-alert
                message="请先将基本信息录入并保存后！再录入其他信息！"
                type="warning" banner 
                show-icon
              />
            </u-table-header>
            <a-collapse v-model:activeKey="activeKey"
              :bordered="false"
              @change="collapseChange">
              <a-collapse-panel v-for="item in collapses" 
                :id="item.activeKey" 
                :key="item.activeKey" 
                :style="customStyle"
                :class="{ 'u-hide-collapse-panel': item.type == 'table' && !formInfo['base']['keyid'] }"
                v-bind="item['props'] || {}">
                <template #header>
                  {{ item.label }}
                  <b class="f-margin-l6">{{ getDetialSize(item.activeKey, item) }}</b>
                </template>
                <template #extra>
                  <a-space style="color: #1890ff" v-if="item.type != 'form' && !isCheck"
                    @click="(e) => toEdit(item, e)">
                    <u-icon-font type="icon-xiugai"></u-icon-font>编辑
                  </a-space>
                </template>
                <template v-if="item.type == 'form'">
                  <u-form :elements="item.els"
                    :model="formInfo[item.activeKey]"
                    :gutter="16"
                    :disabled="isCheck"
                    :loading="formLoading"
                    @formChange="formChange"
                    ref="formRef">
                  </u-form>
                </template>
                <template v-else-if="item.type == 'table'">
                  <u-table :columns="item.els" 
                    :data="formInfo[item.activeKey]"
                    :rowSelection="null"
                    :pagination="false"
                    :loading="formLoading || loadingTypeBusi[`${item.activeKey}Loading`]"
                    :scroll="{ y: '300px' }">
                  </u-table>
                </template>
              </a-collapse-panel>
            </a-collapse>
          </a-tab-pane>
        </u-flow-tab>
      </a-layout-content>
    </a-layout>
    <template #footerBefore>
      <template v-if="route.params.pType == '2' && formInfo['base']['status'] == '2'">
        <u-icon-button itype="approve" @click="auditAbout('2')">批准</u-icon-button>
        <u-icon-button itype="close" @click="auditAbout('3')">退回</u-icon-button>
      </template>
    </template>
  </u-dialog>

  <EditDetials v-model:open="showDetialEdit"
    :params="editParams"
    :baseInfo="formInfo['base'] || {}"
    @success="editSuccess"
    @close="showDetialEdit = false"/>
</template>

<script lang='ts' setup>
import { ref, reactive, computed, onMounted, h, useAttrs, watch, nextTick } from 'vue' 
import { useLoginStore,  useBaseStore } from '@/store'
import { storeToRefs } from 'pinia'
import { useRoute, useRouter } from 'vue-router'
import { _IFormEl, _IExtra } from '@/components/common/form/interface';
import { FormInstance, FormItemProps, AnchorProps } from 'ant-design-vue';
import { _IColumnProps } from '@/components/common/tableEdit/interface.ts'
import { cloneDeep } from 'lodash'
import { alertC, messageC, numberC, isValue, nullC } from '@/util/common'
import { collapses } from './data/data.ts'
import EditDetials from './EditDetial.vue'
import { getCurrentApi } from '@/views/oa/personnelManager/personInfo/data/api.ts'
import { personInfoApi } from '@/service/personalSet' 
import { useAuditAbout } from '@/hooks/useAudit.ts'
import dayjs from 'dayjs'

const props = withDefaults(
  defineProps<{
    current?: object | any
  }>(),
  { current: {} }
)
const route = useRoute()
const attrs = useAttrs()
const { userInfo } = storeToRefs(useLoginStore())
const baseStore = useBaseStore()
const { deptData  } = storeToRefs(baseStore)

const emits = defineEmits(['detialSuccess', 'success'])

// 表单相关信息
const formRef = ref<FormInstance>()
const formLoading = ref<boolean>(false)
const loadingTypeBusi = ref<{[key: string]: boolean}>({})
const auditRef = ref<FormInstance>()

const formInfo = ref<object>({})
const isCheck = computed(() => {
  let baseInfo = formInfo.value['base'] || {}
  return ['2', '3'].includes(baseInfo['status'] + '')
})

// 获取详情的条数
const getDetialSize = (activeKey, item) => {
  if(item.type != 'table') {
    return ''
  }
  let datas = formInfo.value[activeKey] || []
  return datas.length == 0 ? '' : `(${ datas.length }条)`
}

// 所有元素类型
const customStyle = 'background: #fff; border-radius: 4px; margin-bottom: 24px;border: 0;';
let activeKey = ref(['base'])
const initForm = () => {
  formInfo.value = {};
  collapses.forEach(o => {
    formInfo.value[o.activeKey] = o.type == 'form' ? reactive({}) : reactive([])
  })
}

// 确认提交
const submit = async () => {
  // 保存基本信息
  savePersonInfo()
}

// 保存人事基本信息
const savePersonInfo = async() => {
  formLoading.value = true;
  try {
    for(let i = 0; i < formRef.value.length; i++) {
      await formRef.value[i].form.validate()
    }
  } catch (error) {
    formLoading.value = false;
    messageC("请现将表单信息填写完毕！");
    return
  }

  formLoading.value = true;
  try {
    const url = formInfo.value['base']['keyid'] ? 'update' : 'add'
    const res = await personInfoApi[url](formInfo.value['base'] || {});
    if(res.code == 0) {
      if(res.data) {
        formInfo.value['base'] = res.data
      }
      messageC(res.msg, "success");
      emits('success')
      // dialogClose()
    }
    else {
      messageC(res.msg);
    }
  } catch (error) {}
  formLoading.value = false;
}

// 初始化默认保存传递的数据
const initBaseInfo = () => {
  return {
    departmentId: userInfo.value["deptId"],
    departmentName: userInfo.value["deptName"],
  }
}

// 前往编辑页面
let editParams = ref<object>({})
let showDetialEdit = ref<boolean>(false)
const toEdit = (item, e) => {
  e.stopPropagation();
  editParams.value = item;
  showDetialEdit.value = true
}

// 表单change
const formChange = ({ key, value}) => {
  if(key == "departmentId") {
    let dept = deptData.value.find(i => i.value == value);
    formInfo.value['base']['departmentName'] = dept ? dept['label'] : ''
  }
  // 身份证号
  else if(key == 'idCardNo') {
    let year = (value || '').substring(6, 10);
    let month = (value || '').substring(10, 12);
    let day = (value || '').substring(12, 14);
    formInfo.value['base']['perAge'] = year.length == 4 ? numberC(new Date().getFullYear()) - numberC(year) : 0

    if(formInfo.value['base']['perAge'] < 0) {
      formInfo.value['base']['perAge'] = 0
    }

    if(year.length == 4 && month.length == 2 && day.length == 2) {
      formInfo.value['base']['dateOfBirth'] = `${year}-${month}-${day}`
    }
    else {
      formInfo.value['base']['dateOfBirth'] = ''
    }
  }
  // 出生年月
  else if(key == 'dateOfBirth') {
    formInfo.value['base']['perAge'] = value ? dayjs().diff(dayjs(value), 'year') : 0
  }
  // 参加工作年月
  else if(key == 'employmentYears') {
    formInfo.value['base']['companyAge'] = value ? dayjs().diff(dayjs(value), 'year') : 0
  }
}

// 其他具体项编辑保存回调
const editSuccess = async (activeKey: string) => {
  emits('detialSuccess')
  showDetialEdit.value = false
  const api = getCurrentApi(activeKey);
  if(!api) {
    return
  }

  loadingTypeBusi[`${activeKey}Loading`] = true
  try {
    const res = await api.page({
      model: { 
        keywords: null, 
        perInfoNoId: nullC(formInfo.value['base']['keyid'])
      },
      current: 1,
      size: 2000,
    })
    if(res.code == 0) {
      formInfo.value[activeKey] = res.data.records || []

      if(activeKey == 'education') {
        let maxGraduates = formInfo.value[activeKey].filter(i => i.isHighestDegree == 1)
        getMaxGraduate(maxGraduates)
      }
      else if(activeKey == 'job') {
        getNowJob(formInfo.value[activeKey])
      }
    }
  } catch (error) {}
  loadingTypeBusi[`${activeKey}Loading`] = false
}

// 数据回显
const echoInfo = async () => {
  formLoading.value = true;
  try {
    const res = await personInfoApi.query(props.current['keyid'])
    if(res.code == 0) {
      formInfo.value['base'] = res.data || {}

      const dyKeys = {
        // education: 'perDegrees',
        technical: 'perTechnicals',
        expert: 'perAppointedExperts',
        certificate: 'perCredentials',
        job: 'perJobs',
        contract: 'perContracts',
        award: 'perCommends',
        punish: 'perPunishments',
        outsend: 'perDispatches',
        yearcheck: 'perAnnualAssessments',
        family: 'perFamilies',
        emergencyLink: 'perPhones',
        scientific: 'perScientificResearches',
      }
      for(let key in dyKeys) {
        let data = res.data[dyKeys[key]] || [];
        data.forEach(item => {
          item.appendixSaveVOList = item.attachList || []
        })
        formInfo.value[key] = data
      }
      
      echoEducation(res.data || {})

      getNowJob(res.data['perJobs'] || [])
     
    }
  } catch (error) { }
  formLoading.value = false;
}

// 回显学历
const echoEducation = (data) => {
  // 学历回显
  let { perDegreeInitVos, perDegreeJobVos, perDegreeMaxVos } = data || {}
  let equEducationKeys = ['degreeName', 'degreeForm', 'degreeCertificate', 'professionType', 'certificate', 'graduationTime', 'school', 'profession']
  let maxDegrees = (perDegreeMaxVos || []).map(item => {
    item.isInitialDegree = (perDegreeInitVos || []).filter(i => i.keyid == item.keyid) ? '1' : '0';
    equEducationKeys.forEach(key => {
      item.isHighestDegree = '1';
      if(item[key + 'Max']) {
        item[key] = item[key + 'Max']
      }
    })
    return item
  })
  getMaxGraduate(maxDegrees)
  let maxDegreeIds = maxDegrees.map(i => i.keyid)

  let jobDegrees = (perDegreeJobVos || []).filter(i => !maxDegreeIds.includes(i.keyid)).map(item => {
    item.isInitialDegree = (perDegreeInitVos || []).filter(i => i.keyid == item.keyid) ? '1' : '0';
    item.isHighestDegree = '0';
    equEducationKeys.forEach(key => {
      if(item[key + 'Job']) {
        item[key] = item[key + 'Job']
      }
    })
    return item
  })
  
  let initDegrees = (perDegreeInitVos || []).filter(i => !maxDegreeIds.includes(i.keyid)).map(item => {
    equEducationKeys.forEach(key => {
      item.isInitialDegree = '1';
      item.isHighestDegree = '0';
      if(item[key + 'Init']) {
        item[key] = item[key + 'Init']
      }
    })
    return item
  })
  formInfo.value['education'] = [...(initDegrees || []), ...(maxDegrees || []), ...(jobDegrees || [])]
}

// 获取最高学历
const getMaxGraduate = (data) => {
  let maxGraduates = (data || []).map(i => {
    let info = baseStore.storeeducations.find(o => o.value == i.degreeName);
    return info ? info['value'] : ''
  }).filter(i => isValue(i))

  formInfo.value['base']['highestDegree'] = maxGraduates.length == 0 ? '' : maxGraduates[0]
}

// 获取当前职务
const getNowJob = (data) => {
  formInfo.value['base']['perJob'] = data.filter(i => i.isPresentPosition == '1').map(o => o.job).join('/')
}

// 锚点高亮
const refreshAnchor = ref<boolean>(true)
const getCurrentAnchor = () => {
  return nowAnchor.value
}

// 面板change
const collapseChange = (key) => {
  nowAnchor.value = `#${key[key.length - 1]}`
  refreshAnchor.value = false;
  nextTick(() => refreshAnchor.value = true)
  handleClick('', { href: nowAnchor.value })
}

// 锚点点击
const nowAnchor = ref<string>('#base')
const handleClick: AnchorProps['onClick'] = (e, link) => {
  if(e) {
    e.preventDefault();
  }
  if(link['href']) {
    nowAnchor.value = link['href']
    let key = link['href'].replace('#', '')
    if(!activeKey.value.includes(key)) {
      activeKey.value.push(key)
    }
    let dom = document.getElementById(key)
    if(dom) {
      setTimeout(() => dom.scrollIntoView({'behavior': "smooth"}), 500)
    }
  }
};

// 上报、审核、退回
const auditAbout = async (type: string) => {
  formLoading.value = true;
  const auditParams: IAuditParams = {
    type: 'person_info',
    selDatas: [ formInfo.value['base'] ],
    confirm: false,
    isDialog: false
  }
  try {
    const res = await useAuditAbout(type, auditParams, auditRef)
    if(res.error == 200) {
      emits("success");
      dialogClose()
    } 
  } catch (error) {}
  formLoading.value = false;
}

// 滚动锁定锚点
const scrollDiffAnchor = () => {
  try {
    let dom = document.getElementById('rc-tabs-1-panel-1');
    // 获取所有元素
    const allElements = dom.getElementsByClassName('ant-collapse-item');
  
    const filterVisibleEl = () => {
      
      // 获取视窗的高度和宽度
      const viewportHeight = window.innerHeight;
      const viewportWidth = window.innerWidth;
        
      // 过滤出可视区域的元素
      const visibleElements = Array.prototype.filter.call(allElements, function(element) {
          const rect = element.getBoundingClientRect();
          return (
              rect.top >= 0 &&
              rect.left >= 0 &&
              rect.bottom <= viewportHeight &&
              rect.right <= viewportWidth
          );
      });
      if((visibleElements || []).length != 0) {
        nowAnchor.value = `#${visibleElements[0].id}`
        refreshAnchor.value = false;
        nextTick(() => refreshAnchor.value = true)
      }
    }
  
    dom.addEventListener('scroll', (event) => {
      filterVisibleEl()
    })
  } catch (error) {}
}

// 弹窗关闭
const dialogClose = () => {
  activeKey.value = ['base']
  initForm()
  // formRef.value.form.resetFields()
}

watch(() => attrs.open, async (nval, oval) => {
  if (nval == true) {
    if(props.current['keyid']) {
      echoInfo();
    }
    initForm()
    nextTick(() => scrollDiffAnchor())
  }
})
</script>

<style lang='scss' >
.u-personal-manager-edit {
  background: unset !important;
  .ant-collapse-item-disabled {
    .ant-collapse-header {
      cursor: default;
      .ant-collapse-header-text {
        color: rgba(0, 0, 0, 0.88)
      }
    }
  }
  .u-sider-box {
    background: #fff; 
    border-right: 1px solid #eee
  }
  .u-hide-collapse-panel {
    display: none;
  }
  .u-person-flow-tab {
    .ant-tabs-tabpane {
      overflow: auto;
    }
  }
}
</style>